package be.groept.ace.cursusplanning.model;

import be.groept.ace.cursusplanning.persistency.IPersistentieController;
import be.groept.ace.cursusplanning.persistency.IPersistentieProvider;
import be.groept.ace.cursusplanning.persistency.Persisteerbaar;
import be.groept.ace.cursusplanning.utils.Datum;

/**
 * 
 * @author Gouke
 *
 */

public class Inschrijving implements Comparable<Inschrijving>, Persisteerbaar{
	
	private Datum inschrijvingsDatum;
	private Cursist cursist;
	private AangebodenCursus aangebodenCursus;
	private int eerstejaarVanSchooljaar;
	
	private IPersistentieProvider pProvider;
	/**
	 * Maakt een nieuwe Inschrijving aan
	 * @param inschrijvingsDatum
	 * @param cursist
	 * @param aangebodenCursus
	 * @throws IllegalArgumentException
	 */
	public Inschrijving (Datum inschrijvingsDatum, Cursist cursist, AangebodenCursus aangebodenCursus) throws IllegalArgumentException{
		setInschrijvingsDatum(inschrijvingsDatum);
		setEerstejaarVanSchooljaar(inschrijvingsDatum.getJaar());
		setCursist(cursist);
		setAangebodenCursus(aangebodenCursus);
	}
	
	/**
	 * Geeft de inschrijvingsdatum
	 * @return Datum
	 * 			inschrijvingsdatum
	 */
	public Datum getInschrijvingsDatum() {
		return inschrijvingsDatum;
	}
	
	private void setInschrijvingsDatum(Datum inschrijvingsDatum){
		if (inschrijvingsDatum == null) { throw new IllegalArgumentException("Datum mag geen null waarde zijn");}
		this.inschrijvingsDatum = inschrijvingsDatum;
	}
	
	/**
	 * Geeft de cursist terug
	 * @return Cursist
	 * 				cursist
	 */
	public Cursist getCursist(){
		return this.cursist;
	}
	
	private void setCursist(Cursist cursist) {
		if (cursist == null) { throw new IllegalArgumentException("Cursist mag geen null waarde zijn");}
		this.cursist = cursist;
	}
	
	/**
	 * Geeft de aangeboden cursus
	 * @return AangebodenCursus
	 * 					Aangeboden cursus
	 */
	public AangebodenCursus getAangebodenCursus(){

		return this.aangebodenCursus;
	}
	
	private void setAangebodenCursus(AangebodenCursus aangebodenCursus) {
		if (aangebodenCursus == null) { throw new IllegalArgumentException("aangebodenCursus mag geen null waarde zijn");}
		this.aangebodenCursus = aangebodenCursus;
	}
	
	/**
	 * Geeft het eeste jaar van het schooljaar als integer
	 * @return int
	 * 				Eerstejaar
	 */
	public int getEersteJaarVanSchooljaar(){
		return this.eerstejaarVanSchooljaar;
	}
	
	private void setEerstejaarVanSchooljaar(int eerstejaar){
		this.eerstejaarVanSchooljaar = eerstejaar;
	}

	/**
	 * Gebaseerd op aangeboden cursus, op inschrijvingsdatum
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime
				* result
				+ ((aangebodenCursus == null) ? 0 : aangebodenCursus.hashCode());
		result = prime * result + ((cursist == null) ? 0 : cursist.hashCode());
		result = prime * result
				+ ((inschrijvingsDatum == null) ? 0 : inschrijvingsDatum.hashCode());
		return result;
	}

	/**
	 * gebaseerd op aangeboden cursus, cursist en op het schooljaar
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Inschrijving other = (Inschrijving) obj;
		if (aangebodenCursus == null) {
			if (other.aangebodenCursus != null)
				return false;
		} else if (!aangebodenCursus.equals(other.aangebodenCursus))
			return false;
		if (cursist == null) {
			if (other.cursist != null)
				return false;
		} else if (!cursist.equals(other.cursist))
			return false;
		if (inschrijvingsDatum == null) {
			if (other.inschrijvingsDatum != null)
				return false;
		} else if (eerstejaarVanSchooljaar != other.getEersteJaarVanSchooljaar())
			return false;
		return true;
	}

	/**
	 * Vergelijken op cursist, dan schooljaar en dan aangebodencursus
	 */
	@Override
	public int compareTo(Inschrijving inschrijving) { 
		//Zijn de cursisten gelijk? 
		if(this.getCursist().compareTo(inschrijving.getCursist()) == 0) {
			// JA, cursisten zijn gelijk. Zijn de datums gelijk?
			if (this.getInschrijvingsDatum().compareTo(inschrijving.getInschrijvingsDatum()) == 0){ 
				// datums zijn gelijk dus vergelijken op aangeboden cursus
				return this.getAangebodenCursus().compareTo(inschrijving.getAangebodenCursus());
			}
			else{
				// cursisten zijn gelijk,maar datums niet --> vergelijken op datum
				return this.getInschrijvingsDatum().compareTo(inschrijving.getInschrijvingsDatum());
			}
		}
		else{
			// NEEN, cursisten zijn niet gelijk --> vergelijken op cursisten
			return this.getCursist().compareTo(inschrijving.getCursist());
		}
	}
	
	@Override
	public String toString() {
		return "Inschrijving op " + getInschrijvingsDatum() +  " voor " + getCursist() + " voor de cursus " + getAangebodenCursus().toString();
	}

	@Override
	public Object[] getInfoToBeSaved(IPersistentieController pController) {
		return pProvider.getInfoToBeSaved(pController);
		
	}
	public IPersistentieProvider getPersistentieProvider(){
		return pProvider;
	}
	public void setPersistentieProvider(IPersistentieProvider provider){
		this.pProvider = provider;
	}

}
